
AddCSLuaFile("cl_init.lua")
AddCSLuaFile("shared.lua")


include('shared.lua')

if not (WireAddon == nil) then
    ENT.WireDebugName = "LifeCube Ultra Generator"
end

----------variables------------

------------------------------------VARIABLES END
function ENT:SpawnFunction( ply, tr )

 	if ( !tr.Hit ) then return end 
 	 
 	local SpawnPos = tr.HitPos + tr.HitNormal * 10 
 	 
 	local ent = ents.Create( "sent_lifecube_ultragen" )
	ent:SetPos( SpawnPos ) 
 	ent:Spawn()
 	ent:Activate() 
 	ent.Owner = ply
	return ent 
 	 
end

function ENT:Initialize()

	self.Entity:SetModel("models/mattster/MB-ultragen/lifesupport-tank2.mdl")
	self.Entity:SetColor(255, 255, 255, 255)
	self.Entity:SetOwner(self.Owner)
	self.Entity:PhysicsInit(SOLID_VPHYSICS)
	self.Entity:SetMoveType(MOVETYPE_VPHYSICS)
	self.Entity:SetSolid(SOLID_VPHYSICS)

	self.Entity:SetSolid(SOLID_VPHYSICS)	
    local phys = self.Entity:GetPhysicsObject()
	if(phys:IsValid()) then phys:Wake() end
	
	self.MaxAllGas = 1000000000	
	self.MaxEnergy = 1000000000
	self.MaxZPE = 1000000000 -- 1 Billion (It's the lifecube after all...)
	
	if self.RDValid() then
		-- CAF.GetAddon("Resource Distribution").AddResource(self,"energy",0)
		-- CAF.GetAddon("Resource Distribution").AddResource(self,"ZPE",0)
		
		-- CAF.GetAddon("Resource Distribution").AddResource(self,"carbon dioxide",0)
		-- CAF.GetAddon("Resource Distribution").AddResource(self,"hydrogen",0)
		-- CAF.GetAddon("Resource Distribution").AddResource(self,"nitrogen",0)
		-- CAF.GetAddon("Resource Distribution").AddResource(self,"oxygen",0)
		-- CAF.GetAddon("Resource Distribution").AddResource(self,"water",0)
		-- CAF.GetAddon("Resource Distribution").AddResource(self,"steam",0)
		-- CAF.GetAddon("Resource Distribution").AddResource(self,"heavy water",0)
		-- CAF.GetAddon("Resource Distribution").AddResource(self,"liquid nitrogen",0)
		-- CAF.GetAddon("Resource Distribution").AddResource(self,"hot liquid nitrogen",0)
		-- CAF.GetAddon("Resource Distribution").AddResource(self,"Natural Gas",0)
		-- CAF.GetAddon("Resource Distribution").AddResource(self,"Methane",0)
		
		CAF.GetAddon("Resource Distribution").AddResource(self,"energy",self.MaxEnergy,1000)	
		CAF.GetAddon("Resource Distribution").AddResource(self,"ZPE",self.MaxZPE,1000)	
		
		CAF.GetAddon("Resource Distribution").AddResource(self,"carbon dioxide",self.MaxAllGas,1000)
		CAF.GetAddon("Resource Distribution").AddResource(self,"hydrogen",self.MaxAllGas,1000)
		CAF.GetAddon("Resource Distribution").AddResource(self,"nitrogen",self.MaxAllGas,1000)
		CAF.GetAddon("Resource Distribution").AddResource(self,"oxygen",self.MaxAllGas,1000)
		CAF.GetAddon("Resource Distribution").AddResource(self,"water",self.MaxAllGas,1000)
		CAF.GetAddon("Resource Distribution").AddResource(self,"steam",self.MaxAllGas,1000)
		CAF.GetAddon("Resource Distribution").AddResource(self,"heavy water",self.MaxAllGas,1000)
		CAF.GetAddon("Resource Distribution").AddResource(self,"liquid nitrogen",self.MaxAllGas,1000)
		CAF.GetAddon("Resource Distribution").AddResource(self,"hot liquid nitrogen",self.MaxAllGas,1000)
		CAF.GetAddon("Resource Distribution").AddResource(self,"Natural Gas",self.MaxAllGas,1000)
		CAF.GetAddon("Resource Distribution").AddResource(self,"Methane",self.MaxAllGas,1000)
		
	end
	
	-- if not (WireAddon == nil) then self.Inputs = Wire_CreateInputs(self.Entity, { "On", "Multiplier" }) end
	-- if not (WireAddon == nil) then self.Outputs = Wire_CreateOutputs(self.Entity, { "On", "Integrity"}) end
	-- if not (WireAddon == nil) then self.Inputs = Wire_CreateInputs(self.Entity, { "Unload" }) end
	-- if not (WireAddon == nil) then self.Outputs = Wire_CreateOutputs(self.Entity, { "Integrity", "energy", "ZPE"}) end
	
	if WireLib then
		self.WireDebugName = "LifeCube Ultra Generator"
		self.Inputs = WireLib.CreateInputs(self, { "On", "Multiplier",  "Unload" })
		self.Outputs = WireLib.CreateOutputs(self, { "On", "Output" , "Integrity", "energy", "ZPE"})
	else
		self.Inputs = {{Name="On"}}
	end
	
	----------variables------------
	self.Enabled = 0
	self.OverloadP = 0
	self.Integrity = 0
	self.mul = 1
	--Gen Amounts
	self.energysup = 10000
	self.ZPEsup = 10000
	self.Naquadasup = 10000
	
	self.gassup = 10000
	
	self.Sound = CreateSound( self.Entity, "ambient/atmosphere/underground_hall_loop1.wav" )

end

function ENT:RDValid()
	if(CAF and CAF.GetAddon("Resource Distribution")) then
		RD = CAF.GetAddon("Resource Distribution");
		return true;
	end
	return false;
end

----------THINK
function ENT:Think()

	if ( self.Enabled == 1 ) then
		self:GenerateEnergy()
	end
	
	if self.OverloadP > 950 then
		local efx = EffectData()
		efx:SetStart( self.Entity:GetPos() )
		efx:SetOrigin( self.Entity:GetPos()  )
		efx:SetScale( 1 )
		util.Effect( "egenBlackSmoke", efx )
		self.Entity:EmitSound("lifecube/overloading.mp3", 100, 100)
	end
	
	
	--self.Entity:SetNWInt( "IsItOn", self.OnOrOff )
	--self.Entity:SetNWInt( "IsNosConnected", self.NosConnected )
	--self.Entity:SetNWInt( "IsBatteryConnected", self.BatteryConnected )


	if self.Entity:WaterLevel() > 0 then
		if (self.Enabled == 1) then
			self:Overload(10)
			self:TurnOff()
		end

	end
	
	--Supply Multipliers
	self.Integrity = (1000 - self.OverloadP) / 10
	self.energysup = 10000 * self.mul * (self.Integrity / 100)
	self.ZPEsup = 10000 * self.mul * (self.Integrity / 100)
	self.gassup = 10000 * self.mul * (self.Integrity / 100)
	
	if not (WireAddon == nil) then Wire_TriggerOutput(self.Entity, "Integrity", self.Integrity) end
	
	self.Entity:NextThink( CurTime() + 1 )
	return true
end

function ENT:Update()
	if self.RDValid() then
		local RD = CAF.GetAddon("Resource Distribution")
		self.energy =  RD.GetResourceAmount(self.Entity,"energy")
		self.ZPE =  RD.GetResourceAmount(self.Entity,"ZPE")
		if not (WireAddon == nil) then 
			Wire_TriggerOutput(self.Entity, "energy", self.energy) 
			Wire_TriggerOutput(self.Entity, "ZPE", self.ZPE)
			Wire_TriggerOutput(self.Entity, "Integrity", self.Integrity) 
		end
	end
end

function ENT:GenerateEnergy()
	if self.RDValid() then
		local RD = CAF.GetAddon("Resource Distribution")
		if ( self:CanRun() ) then
			RD.SupplyResource(self, "energy", self.energysup)
			RD.SupplyResource(self, "ZPE", self.ZPEsup)
			
			RD.SupplyResource(self, "carbon dioxide", self.gassup)
			RD.SupplyResource(self, "hydrogen", self.gassup)
			RD.SupplyResource(self, "nitrogen", self.gassup)
			RD.SupplyResource(self, "oxygen", self.gassup)
			RD.SupplyResource(self, "water", self.gassup)
			RD.SupplyResource(self, "steam", self.gassup)
			RD.SupplyResource(self, "heavy water", self.gassup)
			RD.SupplyResource(self, "liquid nitrogen", self.gassup)
			RD.SupplyResource(self, "hot liquid nitrogen", self.gassup)
			RD.SupplyResource(self, "Natural Gas", self.gassup)
			RD.SupplyResource(self, "Methane", self.gassup)
		end
	end
end

function ENT:CanRun()
	--Test to check if we can generate resources
	--add something to decrease gen amount when starting to overload
	return true
end

function ENT:TriggerInput(iname, value)
	if (iname == "On") then
		if (value > 0) then
			if ( self.Enabled == 0 ) then
				self:TurnOn()
			end
		else
			if ( self.Enabled == 1 ) then
				self:TurnOff()
			end
		end

	end
	
	if (iname == "Multiplier") then
		if (value > 0) then
			self.mul = value
		end

	end
	
	if (iname == "Unload") then
		if (value > 0) then
			self:Flush()
		end

	end
end

function ENT:Leak(amount)
	if self.RDValid() then
		if (self.ZPE > 0) and (self.energy > 0) then
			local RD = CAF.GetAddon("Resource Distribution")
			RD.ConsumeResource(self.Entity,"ZPE",amount*100);
			RD.ConsumeResource(self.Entity,"energy",amount*100);
			self:SubspaceWave()
			
			return true
		end
	end
	return false
end

function ENT:Flush()
	if self.RDValid() then
		local RD = CAF.GetAddon("Resource Distribution")
		if (self.ZPE > 0) and (self.energy > 0) then
			self.Entity:EmitSound("lifecube/discharge.mp3", 60, 250)
			
			RD.ConsumeResource(self.Entity,"ZPE",self.ZPE);
			RD.ConsumeResource(self.Entity,"energy",self.energy);
			--Discharge Effect
			local effectdata = EffectData()
			effectdata:SetStart( self.Entity:GetPos() )
			effectdata:SetOrigin( self.Entity:GetPos()  )
			effectdata:SetScale( 1 )
			util.Effect( "Egeninflate", effectdata ) 
			
			--we also repair the device...
			self:Repair()
			return true
		end
	end
	return false
end

function ENT:AcceptInput(name,activator,caller)
	if name == "Use" and caller:IsPlayer() and caller:KeyDownLast(IN_USE) == false then
		if ( self.Enabled == 0 ) then
			self:TurnOn()
		elseif (self.Enabled == 1) then
			self:TurnOff()
		end
		
	end
end

function ENT:TurnOn()
	self.Enabled = 1
	if not (WireAddon == nil) then Wire_TriggerOutput(self.Entity, "On", 1) end
	--self.Entity:SetMaterial("Models/effects/splodearc_sheet") 
	--Effect
	self:SubspaceWave()
	
	self.Entity:SetColor(0, 0, 255, 255)
	self.Sound:Play()
end



function ENT:TurnOff()
	self.Enabled = 0
	if not (WireAddon == nil) then Wire_TriggerOutput(self.Entity, "On", 0) end
	--self.Entity:SetMaterial("alienate/cubes/cubecover") 
	self.Entity:SetColor(255, 255, 255, 255)
	self:SubspaceWave()
	self.Sound:Stop()
end

function ENT:OnRemove()
	--Shutdown code
	self.Sound:Stop()
end


function ENT:Repair()
	self:SetHealth(self:GetMaxHealth())
	self.OverloadP = 0
	self:TurnOff()
end

function ENT:Destruct()
	if self.RDValid() then
		local RD = CAF.GetAddon("Resource Distribution")
		CAF.GetAddon("Life Support").Destruct( self.Entity )
	end
end

function ENT:Explode()
	local effectdata = EffectData()
	effectdata:SetStart( self.Entity:GetPos() )
	effectdata:SetOrigin( self.Entity:GetPos()  )
	effectdata:SetScale( 1 )
	util.Effect( "Egeninflate", effectdata ) 
	---Explode Sound
	self.Entity:EmitSound("lifecube/cube_explode.mp3", 100, 100)
	
	--------------
	timer.Simple(0.9,function() 
			local effectdata = EffectData()
			effectdata:SetStart( self.Entity:GetPos() )
			effectdata:SetOrigin( self.Entity:GetPos()  )
			effectdata:SetScale( 2 )
			--effectdata:SetMagnitude(2)
			util.Effect( "effect_explosion_cube", effectdata )
			self:DoDamage(200, 1024)
			self:SubspaceWave()
			--Now we remove it
			self:Remove()
	end )
	
end

function ENT:DoDamage(damage, radius)
	local position = self.Entity:GetPos()
	util.BlastDamage(self.Entity, self.Owner, position, radius, damage) 
end

function ENT:OnTakeDamage(dmg)
	if (self.Enabled == 1) then
		local ndmg = 0
		if dmg:IsDamageType (DMG_BULLET) then
			ndmg = (dmg:GetDamage() * 0.01 ) --1% of the damage
			if ndmg > 50 then
				self:TurnOff()
			end
			self:Overload(ndmg)
		else
			ndmg = (dmg:GetDamage() * 0.8 ) --80% damage			
			if ndmg > 200 then
				self:TurnOff()
			end
			self:Overload(ndmg)
		end 
	end	
end 

function ENT:Overload(Percent)
	self.OverloadP = self.OverloadP + Percent --We increase the overload. Which will later be the integrity percentage
	if self.OverloadP >= 1000 then
		self:Explode()
	end
	self.Entity:SetColor(200, 1, 1, 255)
	
	--Overload  effect & Sound
	if self.Entity:WaterLevel() > 0 then
		self.Entity:EmitSound("lifecube/discharge.mp3", 90, 150)
		timer.Simple(0.9,function() if ValidEntity(self.Entity) then self:Lightning_water() end end)
	else
		self.Entity:EmitSound("lifecube/discharge.mp3", 90, 150)
		timer.Simple(0.9,function() if ValidEntity(self.Entity) then self:Lightning() end end)
	end
end


function ENT:Lightning()
	local effectdata = EffectData()
	effectdata:SetStart( self.Entity:GetPos() ) 
	effectdata:SetOrigin( self.Entity:GetPos()  )
	effectdata:SetScale( 1 )
	--effectdata:SetMagnitude(2)
	util.Effect( "egen_Zap", effectdata )
	util.ScreenShake( self.Entity:GetPos(), 5, 5, 1, 500 ) 
end

function ENT:SubspaceWave()
	local efx = EffectData()
	efx:SetStart( self.Entity:GetPos() )
	efx:SetOrigin( self.Entity:GetPos()  )
	efx:SetScale( 1 )
	util.Effect( "egenHeat", efx )
	util.ScreenShake( self.Entity:GetPos(), 5, 5, 1, 500 ) 
end

function ENT:Lightning_water()
	local effectdata = EffectData()
	effectdata:SetStart( self.Entity:GetPos() ) 
	effectdata:SetOrigin( self.Entity:GetPos()  )
	effectdata:SetScale( 1 )
	--effectdata:SetMagnitude(2)
	util.Effect( "egen_Zap_water", effectdata )
	util.ScreenShake( self.Entity:GetPos(), 5, 5, 1, 500 ) 
end
